home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 726-750 / 729 / dsound / source / mem.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  5KB  |  213 lines

  1.  
  2. /**************************************************************************/
  3. /*                   Mem.c                  */
  4. /*Contains code for reading an entire sample into memory at once      */
  5. /*This is used when it isn't practical to read the sound sample from      */
  6. /*disk as it is played (e.g. when the sample is on a floppy).             */
  7. /*Data is read in in blocks that are the same size as the buffer size      */
  8. /*(optionally) specified by the user using the -b flag, thereby not       */
  9. /*requiring the user to have a block of contiguous memory as large as      */
  10. /*the sample.                                  */
  11. /*The memory blocks are stored as a linked list;  there are two linked      */
  12. /*lists, one for each channel of a stereo sample (the list for the left   */
  13. /*channel is used if a mono sample is being played)              */
  14. /**************************************************************************/
  15.  
  16. #include <exec/types.h>
  17. #include <dos/dos.h>
  18. #include <dos/dosextens.h>
  19.  
  20. #include <proto/dos.h>
  21. #include <proto/exec.h>
  22.  
  23. #include "dsound.h"
  24.  
  25. typedef struct memBlock
  26. {
  27.    struct memBlock *next;  /*The next memory block in the list*/
  28.    ULONG blockLength;       /*The size of this memory block*/
  29. } memBlock;
  30.  
  31. /*The linked-list head pointers for each channel*/
  32. memBlock *left=NULL;
  33. memBlock *right=NULL;
  34.  
  35. /*Read the sample (pointed to by file) into memory*/
  36. void storeLeft(BPTR file,ULONG length,ULONG blockLength)
  37. {
  38.    memBlock *temp;
  39.    memBlock *lastLeft;
  40.  
  41.    /*Loop while there's data to be stored...*/
  42.    while(length!=0)
  43.    {
  44.       /*Get the amount of data to be read next (max of blockLength bytes)*/
  45.       blockLength=MIN(blockLength,length);
  46.  
  47.       /*Allocate the memory*/
  48.       temp=(memBlock *)AllocMem(blockLength+8,0L);
  49.  
  50.       /*Exit if there was a problem*/
  51.       if(temp==NULL)
  52.       {
  53.      WriteMsg("Couldn't allocate needed memory\n");
  54.      cleanup(500);
  55.       }
  56.  
  57.       /*Get the length of the data block*/
  58.       temp->blockLength=blockLength;
  59.       temp->next=NULL;
  60.  
  61.       if(left==NULL)
  62.      left=lastLeft=temp;  /*First block of data...*/
  63.       else
  64.       {        /* Add another block to the end of the list*/
  65.      lastLeft->next=temp;
  66.      lastLeft=temp;
  67.       }
  68.  
  69.       /*Actually read the data, now that the allocated memory block*/
  70.       /*is in place*/
  71.       Read(file,lastLeft+1,blockLength);
  72.  
  73.       /*Subtract the amount read from the total yet to read*/
  74.       length-=blockLength;
  75.    }
  76.  
  77.    return;
  78. }
  79.  
  80. /*Delete any remaining memory blocks associated with the left channel*/
  81. void deleteLeft(void)
  82. {
  83.    memBlock *temp,*next;
  84.  
  85.    next=left;
  86.  
  87.    /*Loop until we run out of memory blocks*/
  88.    while(next!=NULL)
  89.    {
  90.       /*Get the next block*/
  91.       temp=next;
  92.       next=temp->next;
  93.  
  94.       /*Free the current block*/
  95.       FreeMem(temp,temp->blockLength+8);
  96.    }
  97.  
  98.    return;
  99. }
  100.  
  101. /*Get the next available block of sample data associated with the */
  102. /*left channel*/
  103. void getLeft(APTR dest)
  104. {
  105.    memBlock *temp;
  106.  
  107.    /*If there is no data left, do nothing*/
  108.    if(dest==NULL || left == NULL)
  109.       return;
  110.  
  111.    /*Copy the sample data from the memory block to the destination buffer*/
  112.    CopyMem(left+1,dest,left->blockLength);
  113.  
  114.    /*Set the next block as the head of the list*/
  115.    temp=left;
  116.    left=left->next;
  117.  
  118.    /*Free the memory whose contents we just copied*/
  119.    FreeMem(temp,temp->blockLength+8);
  120.  
  121.    return;
  122. }
  123.  
  124. /*Read the sample (pointed to by file) into memory*/
  125. void storeRight(BPTR file,ULONG length,ULONG blockLength)
  126. {
  127.    memBlock *temp;
  128.    memBlock *lastRight;
  129.  
  130.    /*Loop while there's data to be stored...*/
  131.    while(length!=0)
  132.    {
  133.       /*Get the amount of data to be read next (max of blockLength bytes)*/
  134.       blockLength=MIN(blockLength,length);
  135.  
  136.       /*Allocate the memory*/
  137.       temp=(memBlock *)AllocMem(blockLength+8,0L);
  138.  
  139.       /*Exit if there was a problem*/
  140.       if(temp==NULL)
  141.       {
  142.      WriteMsg("Couldn't allocate needed memory\n");
  143.      cleanup(500);
  144.       }
  145.  
  146.       /*Get the length of the data block*/
  147.       temp->blockLength=blockLength;
  148.       temp->next=NULL;
  149.  
  150.       if(right==NULL)
  151.      right=lastRight=temp;    /*First block of data...*/
  152.       else
  153.       {        /* Add another block to the end of the list*/
  154.      lastRight->next=temp;
  155.      lastRight=temp;
  156.       }
  157.  
  158.       /*Actually read the data, now that the allocated memory block*/
  159.       /*is in place*/
  160.       Read(file,lastRight+1,blockLength);
  161.  
  162.       /*Subtract the amount read from the total yet to read*/
  163.       length-=blockLength;
  164.    }
  165.  
  166.    return;
  167. }
  168.  
  169. /*Delete any remaining memory blocks associated with the right channel*/
  170. void deleteRight(void)
  171. {
  172.    memBlock *temp,*next;
  173.  
  174.    next=right;
  175.  
  176.    /*Loop until we run out of memory blocks*/
  177.    while(next!=NULL)
  178.    {
  179.       /*Get the next block*/
  180.       temp=next;
  181.       next=temp->next;
  182.  
  183.       /*Free the current block*/
  184.       FreeMem(temp,temp->blockLength+8);
  185.    }
  186.  
  187.    return;
  188. }
  189.  
  190. /*Get the next available block of sample data associated with the */
  191. /*right channel*/
  192. void getRight(APTR dest)
  193. {
  194.    memBlock *temp;
  195.  
  196.    /*If there is no data right, do nothing*/
  197.    if(dest==NULL || right == NULL)
  198.       return;
  199.  
  200.    /*Copy the sample data from the memory block to the destination buffer*/
  201.    CopyMem(right+1,dest,right->blockLength);
  202.  
  203.    /*Set the next block as the head of the list*/
  204.    temp=right;
  205.    right=right->next;
  206.  
  207.    /*Free the memory whose contents we just copied*/
  208.    FreeMem(temp,temp->blockLength+8);
  209.  
  210.    return;
  211. }
  212.  
  213.